{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多变量线性回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Size</th>\n",
       "      <th>Bedrooms</th>\n",
       "      <th>Price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2104</td>\n",
       "      <td>3</td>\n",
       "      <td>399900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1600</td>\n",
       "      <td>3</td>\n",
       "      <td>329900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2400</td>\n",
       "      <td>3</td>\n",
       "      <td>369000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1416</td>\n",
       "      <td>2</td>\n",
       "      <td>232000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>3000</td>\n",
       "      <td>4</td>\n",
       "      <td>539900</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Size  Bedrooms   Price\n",
       "0  2104         3  399900\n",
       "1  1600         3  329900\n",
       "2  2400         3  369000\n",
       "3  1416         2  232000\n",
       "4  3000         4  539900"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "path =  'ex1data2.txt'\n",
    "data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])\n",
    "data2.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "def computeCost(X, y, theta):#X代表训练集\n",
    "    inner = np.power(((X * theta.T) - y), 2)#theta.T代表theta的转置矩阵\n",
    "    #numpy.power()用于数组元素求n次方，numpy.power(x1, x2) ：x2可以是数字，也可以是数组，但是x1和x2的列数要相同\n",
    "    return np.sum(inner) / (2 * len(X))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 特征归一化（特征缩放）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Size</th>\n",
       "      <th>Bedrooms</th>\n",
       "      <th>Price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.130010</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>0.475747</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.504190</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>-0.084074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.502476</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>0.228626</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.735723</td>\n",
       "      <td>-1.537767</td>\n",
       "      <td>-0.867025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.257476</td>\n",
       "      <td>1.090417</td>\n",
       "      <td>1.595389</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Size  Bedrooms     Price\n",
       "0  0.130010 -0.223675  0.475747\n",
       "1 -0.504190 -0.223675 -0.084074\n",
       "2  0.502476 -0.223675  0.228626\n",
       "3 -0.735723 -1.537767 -0.867025\n",
       "4  1.257476  1.090417  1.595389"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data2 = (data2 - data2.mean()) / data2.std()#.mean(axis=0)等价于.mean(0)，得到每列数据的平均值；.mean(axis=1)得到每行数据的平均值。\n",
    "#.std()用于计算标准差\n",
    "data2.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Ones</th>\n",
       "      <th>Size</th>\n",
       "      <th>Bedrooms</th>\n",
       "      <th>Price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.130010</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>0.475747</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.504190</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>-0.084074</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0.502476</td>\n",
       "      <td>-0.223675</td>\n",
       "      <td>0.228626</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.735723</td>\n",
       "      <td>-1.537767</td>\n",
       "      <td>-0.867025</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>1.257476</td>\n",
       "      <td>1.090417</td>\n",
       "      <td>1.595389</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Ones      Size  Bedrooms     Price\n",
       "0     1  0.130010 -0.223675  0.475747\n",
       "1     1 -0.504190 -0.223675 -0.084074\n",
       "2     1  0.502476 -0.223675  0.228626\n",
       "3     1 -0.735723 -1.537767 -0.867025\n",
       "4     1  1.257476  1.090417  1.595389"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data2.insert(0, 'Ones', 1,allow_duplicates=True)#在data的指定列中插入数据。\n",
    "# 可选参数，如果dataframe中已经存在某列，将allow_duplicates置为true才可以将指定得列插入。\n",
    "data2.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "cols = data2.shape[1]#shape函数是numpy.core.fromnumeric中的函数，它的功能是读取矩阵的长度，\n",
    "#比如shape[0]就是读取矩阵第一维度的长度,相当于行数;shape[1]相当于列数\n",
    "X2 = data2.iloc[:,0:cols-1]#提取所有行，从0列到cols-1列的所有数据\n",
    "y2 = data2.iloc[:,cols-1:cols]#提取所有行，从cols-1列到cols列的所有数据\n",
    "#例：data.iloc[[0,1],[0,1]] #提取第0、1行，第0、1列中的数据\n",
    "\n",
    "# 转换θ矩阵\n",
    "X2 = np.matrix(X2.values)\n",
    "y2 = np.matrix(y2.values)\n",
    "theta2 = np.matrix(np.array([0,0,0]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "#批量梯度下降\n",
    "def gradientDescent(X, y, theta, alpha, iters):\n",
    "    temp = np.matrix(np.zeros(theta.shape))\n",
    "    parameters = int(theta.ravel().shape[1])\n",
    "    cost = np.zeros(iters)\n",
    "    \n",
    "    for i in range(iters):\n",
    "        error = (X * theta.T) - y\n",
    "        \n",
    "        for j in range(parameters):\n",
    "            term = np.multiply(error, X[:,j])\n",
    "            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))\n",
    "            \n",
    "        theta = temp\n",
    "        cost[i] = computeCost(X, y, theta)\n",
    "        \n",
    "    return theta, cost"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "初始化 学习速率α和要执行的迭代次数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "alpha = 0.01\n",
    "iters = 1000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.1307033696077189"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "# 对数据集执行线性回归\n",
    "g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)\n",
    "\n",
    "# 得到模型的成本（误差）\n",
    "computeCost(X2, y2, g2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们也可以快速查看这一个的训练进程。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(12,8))\n",
    "ax.plot(np.arange(iters), cost2, 'r')\n",
    "ax.set_xlabel('Iterations')\n",
    "ax.set_ylabel('Cost')\n",
    "ax.set_title('Error vs. Training Epoch')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
